package sim_moteur.factory;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import sim_moteur.Simulateur.ChosesPossibles;
import sim_moteur.element.Chose;

public class SimFactory extends AbstractFactory {

	private static Map<String, SimFactory> map = new ConcurrentHashMap<>();
	private AnimauxFactory fabriqueAnimaux;
	private VegetauxFactory fabriqueVegetaux;
	private ChoseFactory fabriqueChoses;

	private SimFactory(String prefix) {
		super(prefix);
		fabriqueAnimaux = new AnimauxFactory(prefix);
		fabriqueVegetaux = new VegetauxFactory(prefix);
		fabriqueChoses = new ChoseFactory(prefix);
	}

	/**
	 * Retourne la seule instance de fabrique d'animaux. (singleton) Noter que
	 * chaque thread possède sa propre copie du singleton
	 * 
	 * @return la fabrique
	 */
	public static SimFactory getInstance(String prefix) {
		if (map.get(prefix) == null) {
			map.put(prefix, new SimFactory(prefix));
		}
		return map.get(prefix);
	}

	/**
	 * On reset toutes les factory du simulateur
	 * 
	 * @param string
	 */
	public static void reset(String prefix) {
		map.replace(prefix, new SimFactory(prefix));
	}

	@SuppressWarnings("rawtypes")
	public ChoseFactoryI getFactory(ChosesPossibles sorte) {
		ChoseFactoryI fabrique = null;
		switch (sorte) {
		case ANIMAL:
			fabrique = fabriqueAnimaux;
			break;
		case VEGETAL:
			fabrique = fabriqueVegetaux;
			break;
		case CHOSE:
			fabrique = fabriqueChoses;
			break;
		}
		return fabrique;
	}

	public <T extends Chose> Map<String, T> getAll(ChosesPossibles filtre) {

		@SuppressWarnings("unchecked")
		ChoseFactoryI<T> fabrique = getFactory(filtre);
		HashMap<String, T> retMap = new HashMap<>();
		retMap.putAll(fabrique.getAll());

		return retMap;
	}
}
